package net.sddf.system.bank.business.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.sddf.system.bank.business.AgencyBidService;
import net.sddf.system.bank.business.BalanceDetailsService;
import net.sddf.system.bank.business.BorrowRecordService;
import net.sddf.system.bank.business.model.constant.RemoteReturnCode;
import net.sddf.system.bank.business.model.vo.LoanDetailVo;
import net.sddf.system.bank.business.model.vo.LoanVo;
import net.sddf.system.bank.common.constant.AgencyBidStatus;
import net.sddf.system.bank.common.util.EncryptUtil;
import net.sddf.system.bank.entity.AgencyBid;
import net.sddf.system.bank.entity.BalanceDetails;
import net.sddf.system.bank.entity.BorrowRecord;
import net.sddf.system.bank.mapper.AgencyBidMapper;
import net.sddf.system.bank.model.BankBidDTO;
import net.sddf.system.bank.model.ConfirmLoanResponse;
import net.sddf.system.bank.model.UserAutoPreTransactionResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class AgencyBidServiceImpl extends ServiceImpl<AgencyBidMapper, AgencyBid> implements AgencyBidService {

	@Autowired
	private BalanceDetailsService balanceDetailsService;

	@Autowired
	private BorrowRecordService projectService;

	@Override
	@Transactional
	public UserAutoPreTransactionResponse autoPreTransactionForTender(
			BankBidDTO bankBidDTO) {
		UserAutoPreTransactionResponse response = new UserAutoPreTransactionResponse();
		response.setRequestNo(bankBidDTO.getReqCode());
		response.setBizType(bankBidDTO.getBizType());
		String requestNo = bankBidDTO.getReqCode();

		try {
			// 校验用户余额是否够用
			UserAutoPreTransactionResponse verifyResponse =
					balanceDetailsService.verifyEnough(
							bankBidDTO.getUserCode(),
							bankBidDTO.getAmount(), response);
			if (verifyResponse != null) {
				//返回余额不足错误信息
				return verifyResponse;
			}

			//保存投资申购信息
			AgencyBid agencyBid = new AgencyBid();
			BeanUtils.copyProperties(bankBidDTO, agencyBid);

			agencyBid.setStatus(AgencyBidStatus.FROZEN.getCode());
			save(agencyBid);
			log.info("银行托管系统，保存投资申购信息：{}",agencyBid);

			log.info("冻结用户余额start");
			//冻结用户余额
			balanceDetailsService.freezeBalance(bankBidDTO);
			log.info("冻结用户余额end");


			response.setSuccess();
		} catch (Exception e) {
			log.error(e.getMessage());
			response.setFailure();
		}
		return response;
	}

	@Override
	@Transactional
	public ConfirmLoanResponse confirmLoan(String reqData) {
		String decodeUrlData = EncryptUtil.decodeURL(reqData);
		String decodeReqData = EncryptUtil.decodeUTF8StringBase64(decodeUrlData);

		//拿到数据
		LoanVo request = JSON.parseObject(decodeReqData, LoanVo.class);
		String requestNo = request.getReqCode();

		ConfirmLoanResponse response = new ConfirmLoanResponse();
		response.setRequestNo(requestNo);

		List<LoanDetailVo> loanDetailList = request.getDetails();
		List<AgencyBid> tenderList = new ArrayList<>();
		//获取投资申购记录
		for (LoanDetailVo loan : loanDetailList) {
			AgencyBid agencyBid = getByRequestNo(loan.getPreReqCode());

			//判断投资申购信息是否存在
			if (agencyBid == null) {
				log.warn("投资申购记录{}不存在", loan.getPreReqCode());
				response.setResp(RemoteReturnCode.TENDER_NOT_EXIST);
				return response;
			}
			tenderList.add(agencyBid);
		}

		try {
			//获取原始借款项目信息
			BorrowRecord project =
					projectService.getByProjectNo(tenderList.get(0).getBorrowRecordNo());
			//获取借款人余额信息
			BalanceDetails loanBalanceDetails =
					balanceDetailsService.getByUserNo(project.getUserCode());
			BalanceDetails investBalanceDetails;
			for (AgencyBid tender : tenderList) {
				//扣除投资人冻结金额
				investBalanceDetails = balanceDetailsService.getByUserNo(tender.getUserCode());
				//investBalanceDetails.setAppCode(request.getAppCode());
				investBalanceDetails.setRequestContent(decodeReqData);
				balanceDetailsService.decreaseBalance(investBalanceDetails, tender.getAmount());

				//添加冻结金额到借款人账户
				//loanBalanceDetails.setAppCode(request.getAppCode());
				loanBalanceDetails.setRequestContent(decodeReqData);
				balanceDetailsService.increaseBalance(loanBalanceDetails, tender.getAmount());

				//更新投资申购状态
				modifyTenderStatus(tender.getId(), AgencyBidStatus.LOAN.getCode());
				response.setSuccess();
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			response.setFailure();
		}
		return response;
	}

	/**
	 * 根据请求流水号获取投资申购信息
	 * @param requestNo
	 * @return
	 */
	private AgencyBid getByRequestNo(String requestNo) {
		return getOne(Wrappers.<AgencyBid>lambdaQuery().eq(AgencyBid::getReqCode, requestNo), false);
	}

	/**
	 * 更新投资申购状态
	 * @param tenderStatus
	 * @return
	 */
	private Boolean modifyTenderStatus(Long id, String tenderStatus) {
		return update(Wrappers.<AgencyBid>lambdaUpdate().eq(AgencyBid::getId, id).set(AgencyBid::getStatus, tenderStatus));
	}

}
